if lib and not lib.LoadQuotes then


function lib:LoadQuotes(fn, thread, threads_number, save_fn)
	if threads_number and not thread then return end
	
	local list = self:LoadFile(fn)
	if not list or #list <= 0 then return end

	local iSec = 3
	local iVal = 5
	local str = split(list[1], "\t")
	if #str[1] == 0 then
		iSec = self:GetIndex(str, "Instrument code")
		iVal = self:GetIndex(str, "Val. today")
		if not (iSec and iVal) then return end
		table.remove(list, 1)
	else
		str = split(list[1], ",")
		if string.match(str[1], "^[%d:]+$") then
			iSec = 4
			iVal = 6
		end
	end
	
	list.sort = function(self, small, big)
		if self.iSort < 0 then
			return small[#small + 1 + self.iSort] > big[#big + 1 + self.iSort]
		else
			return small[#small + 1 - self.iSort] < big[#big + 1 - self.iSort]
		end
	end
	
	local quote_metatable = {
		__lt = function(small, big)
			return small.parent:sort(small, big)
		end
	}
	
	-- Liqudity filter
	
	local limit_val = self.global.liquidity_limit
	for i = #list, 1, -1 do
		list[i] = split(list[i], "[\t]")
		if list[i][iVal] then
			list[i][iVal] = tonumber((string.gsub(string.gsub(list[i][iVal], "%.%d%d$", ""), "[%s,]", ""))) or 0
			if (not limit_val or limit_val <= list[i][iVal])
				and list[i][iSec]
				and #list[i][iSec] >= 4
			then
				table.insert(list[i], list[i][iSec])
				table.insert(list[i], list[i][iVal])
				list[i].parent = list
				setmetatable(list[i], quote_metatable)
			else
				table.remove(list, i)
			end
		else
			table.remove(list, i)
		end
	end
	
	-- Deny short filter
	
	local filter = self:LoadFile(lib.path.init .. "short_filter." .. self:GetUser() .. ".ini")
	if filter then
		for _, l in ipairs(filter) do
			filter[l] = true
		end
		
		for i = #list, 1, -1 do
			if filter[list[i][iSec]] then
				table.remove(list, i)
			end
		end
	end
	
	list.iSort = -1
	table.sort(list)
	
	-- Futures filter
	
	filter = {}
	for i = 1, #list do
		str = string.match(list[i][iSec], "^(%a%a)%a%d$")
		if str then
			str = string.upper(str)
			if filter[str] then
				list[i] = false
			else
				filter[str] = true
			end
		end
	end
	for i = #list, 1, -1 do
		if not list[i] then
			table.remove(list, i)
		end
	end
	
	-- Max quantity filter
	
	if self.global.instruments_limit then
		for i = #list, self.global.instruments_limit + 1, -1 do
			table.remove(list, i)
		end
	end
	
	if save_fn then
		list.iSort = 2
		table.sort(list)
		
		self:SaveFile(save_fn, list)
		
		list.iSort = -1
		table.sort(list)
	end
	
	local turnover = 0
	for i = #list, 1, -1 do
		turnover = turnover + list[i][iVal]
	end
		
	local from = 1
	local to = #list
	if threads_number then
		local n = math.ceil(#list / threads_number)
		local nt = turnover / threads_number
		local average, filled, done, nn
		for t = 1, threads_number do
			filled = list[t][iVal]
			list[t][ #list[t] ] = t
			nn = math.min(n, #list - n * (t - 1))
			for i = 2, nn do
				average = (nt - filled) / (nn - i + 1)
				done = nil
				for j = threads_number + 1, #list do
					if list[j][ #list[j] ] > threads_number then
						if list[j][ #list[j] ] <= average then
							list[j][ #list[j] ] = t
							filled = filled + list[j][iVal]
							done = true
							break
						end
					end
				end
				if not done then
					for j = #list, threads_number + 1, -1 do
						if list[j][ #list[j] ] > threads_number then
							list[j][ #list[j] ] = t
							filled = filled + list[j][iVal]
							break
						end
					end
				end
			end
		end		
		
		list.iSort = 1
		table.sort(list)
		
		from = 1 + n * thread
		to = math.min(n * (thread + 1), #list)
	end
	
	local quotes = {}
	for i = from, to do
		list[i] = {
			sec_code = list[i][iSec],
			value = list[i][iVal]
		}
		table.insert(quotes, list[i])
	end
	
	return quotes
end


end -- of file
